﻿using BCCommon;
using BCData.TMS.Agent.AgentNightFreightConfiguration;
using BCData.TMS.Agent.AgentRecord;
using BCData.TMS.NightFreightConfiguration;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.NightFreightConfiguration;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.Agent.AgentNightFreightConfiguration;
using BCEntity.TMS.NightFreightConfiguration;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BCService.TMS.NightFreightConfiguration
{
    public class NightFreightConfigurationService : INightFreightConfigurationService
    {
        private readonly INightFreightConfigurationData nightFreightConfigurationData;
        private readonly IAgentNightFreightConfigurationData agentNightFreightConfigurationData;
        private readonly IAgentRecordData agentRecordData;
        private readonly IRedisService redisService;
        private readonly string key = string.Format("{0}", EntityNameConst.NightFreightConfigurationEntity);
        private readonly string viewKey = string.Format("{0}", EntityNameConst.AgentNightFreightConfigurationEntity);

        public NightFreightConfigurationService(INightFreightConfigurationData nightFreightConfigurationData,
            IAgentNightFreightConfigurationData agentNightFreightConfigurationData,
            IAgentRecordData agentRecordData,
            IRedisService redisService)
        {
            this.nightFreightConfigurationData = nightFreightConfigurationData;
            this.agentNightFreightConfigurationData = agentNightFreightConfigurationData;
            this.agentRecordData = agentRecordData;
            this.redisService = redisService;
        }

        public NightFreightConfigurationViewDto Create(AdminDto admin, NightFreightConfigurationRequestDto requestDto)
        {
            if (admin.AgentRecord == null)
            {
                //总部添加
                var result = this.nightFreightConfigurationData.Insert(new NightFreightConfigurationEntity()
                {
                    OrderExtractProportion = requestDto.OrderExtractProportion,
                    StartHour = requestDto.StartHour,
                    StartMinute = requestDto.StartMinute,
                    EndHour = requestDto.EndHour,
                    EndMinute = requestDto.EndMinute,
                    CreateTime = DateTime.Now,
                    CreateAdminId = admin.AdminId,
                    CreateAdminName = admin.FullName,
                    UpdateTime = DateTime.Now,
                    EditAdminId = admin.AdminId,
                    EditAdminName = admin.FullName
                }).GetAwaiter().GetResult();
                this.redisService.DeleteMultipleKey(key, false);
                return result.As<NightFreightConfigurationViewDto>();
            }
            else
            {
                //代理商添加
                var result = this.agentNightFreightConfigurationData.Insert(new AgentNightFreightConfigurationEntity()
                {
                    AgentRecordId = admin.AgentRecord.AgentRecordId,
                    OrderExtractProportion = requestDto.OrderExtractProportion,
                    StartHour = requestDto.StartHour,
                    StartMinute = requestDto.StartMinute,
                    EndHour = requestDto.EndHour,
                    EndMinute = requestDto.EndMinute,
                    CreateTime = DateTime.Now,
                    CreateAdminId = admin.AdminId,
                    CreateAdminName = admin.FullName,
                    UpdateTime = DateTime.Now,
                    EditAdminId = admin.AdminId,
                    EditAdminName = admin.FullName
                }).GetAwaiter().GetResult();
                this.redisService.DeleteMultipleKey(viewKey, false);
                return result.As<NightFreightConfigurationViewDto>();
            }
        }

        public void Delete(AdminDto admin, long nightFreightConfigurationId)
        {
            var result = this.nightFreightConfigurationData.GetEntity(nightFreightConfigurationId).Result;
            if (result == null)
            {
                throw new ArgumentException("夜间运费配置信息不存在");
            }
            this.nightFreightConfigurationData.Delete(result.NightFreightConfigurationId).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(key, false);
        }

        public void DeleteAgent(AdminDto admin, long agentNightFreightConfigurationId)
        {
            var result = this.agentNightFreightConfigurationData.GetEntity(agentNightFreightConfigurationId).Result;
            if (result == null)
            {
                throw new ArgumentException("代理商夜间运费配置信息不存在");
            }
            this.agentNightFreightConfigurationData.Delete(result.AgentNightFreightConfigurationId).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(viewKey, false);
        }

        public IEnumerable<NightFreightConfigurationViewDto> GetList(AdminDto admin, int? orderExtractProportion, int? startHour, int? startMinute, int? endHour, int? endMinute)
        {
            if (admin.AgentRecord == null)
            {
                string cacheKey = this.redisService.GetKey(key, orderExtractProportion, startHour, startMinute, endHour, endMinute);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var data = this.nightFreightConfigurationData.GetList(orderExtractProportion, startHour, startMinute, endHour, endMinute).Result;
                    return data.As<List<NightFreightConfigurationViewDto>>();
                }, TimeSpan.FromDays(30));
                return result;
            }
            else
            {
                string cacheKey = this.redisService.GetKey(viewKey, admin.AgentRecord.AgentRecordId, orderExtractProportion, startHour, startMinute, endHour, endMinute);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var data = this.agentNightFreightConfigurationData.GetList(admin.AgentRecord.AgentRecordId, orderExtractProportion, startHour, startMinute, endHour, endMinute).Result;
                    if (!data.Any())
                    {
                        var baseData = this.nightFreightConfigurationData.GetList(orderExtractProportion, startHour, startMinute, endHour, endMinute).Result;
                        return data.As<List<NightFreightConfigurationViewDto>>();
                    }
                    return data.As<List<NightFreightConfigurationViewDto>>();
                }, TimeSpan.FromDays(30));
                return result;
            }
        }
        public IEnumerable<NightFreightConfigurationViewDto> GetList(long agentRecordId)
        {
            string cacheKey = this.redisService.GetKey(viewKey, agentRecordId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.agentNightFreightConfigurationData.GetList(agentRecordId, null, null, null, null, null).Result;
                if (!data.Any())
                {
                    var baseData = this.nightFreightConfigurationData.GetList(null, null, null, null, null).Result;
                    return data.As<List<NightFreightConfigurationViewDto>>();
                }
                return data.As<List<NightFreightConfigurationViewDto>>();
            }, TimeSpan.FromDays(30));
            return result;
        }


        public PageableList<NightFreightConfigurationViewDto> Query(AdminDto admin, int? orderExtractProportion, int? startHour, int? startMinute, int? endHour, int? endMinute, int pageIndex, int pageSize)
        {
            if (admin.AgentRecord == null)
            {
                string cacheKey = this.redisService.GetKey(key, orderExtractProportion, startHour, startMinute, endHour, endMinute, pageIndex, pageSize);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var (data, dataCount) = this.nightFreightConfigurationData.Query(orderExtractProportion, startHour, startMinute, endHour, endMinute, pageIndex, pageSize).Result;
                    return new PageableList<NightFreightConfigurationViewDto>()
                    {
                        Count = dataCount,
                        Items = data.As<List<NightFreightConfigurationViewDto>>(),
                        PageIndex = pageIndex,
                        PageSize = pageSize
                    };
                }, TimeSpan.FromDays(30));
                return result;
            }
            else
            {
                string cacheKey = this.redisService.GetKey(viewKey, admin.AgentRecord.AgentRecordId, orderExtractProportion, startHour, startMinute, endHour, endMinute, pageIndex, pageSize);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var (data, dataCount) = this.agentNightFreightConfigurationData.Query(admin.AgentRecord.AgentRecordId, orderExtractProportion, startHour, startMinute, endHour, endMinute, pageIndex, pageSize).Result;
                    if (dataCount == 0)
                    {
                        var (baseData, baseDataCount) = this.nightFreightConfigurationData.Query(orderExtractProportion, startHour, startMinute, endHour, endMinute, pageIndex, pageSize).Result;
                        {
                            return new PageableList<NightFreightConfigurationViewDto>()
                            {
                                Count = dataCount,
                                Items = data.As<List<NightFreightConfigurationViewDto>>(),
                                PageIndex = pageIndex,
                                PageSize = pageSize
                            };
                        }
                    }
                    return new PageableList<NightFreightConfigurationViewDto>()
                    {
                        Count = dataCount,
                        Items = data.As<List<NightFreightConfigurationViewDto>>(),
                        PageIndex = pageIndex,
                        PageSize = pageSize
                    };
                }, TimeSpan.FromDays(30));
                return result;
            }
        }

        public NightFreightConfigurationViewDto Update(AdminDto admin, NightFreightConfigurationPutDto putDto)
        {
            if (admin.CompanyId == 1)
            {
                //如果是总部，则  夜间运费配置ID 不能为空
                if (!putDto.NightFreightConfigurationId.HasValue || putDto.NightFreightConfigurationId.Value <= 0)
                {
                    throw new ArgumentException("夜间运费配置ID不能为空");
                }
                var result = this.nightFreightConfigurationData.GetEntity(putDto.NightFreightConfigurationId.Value).Result;
                if (result == null)
                {
                    throw new ArgumentException("夜间运费配置信息不存在");
                }
                result.OrderExtractProportion = putDto.OrderExtractProportion;
                result.StartHour = putDto.StartHour;
                result.StartMinute = putDto.StartMinute;
                result.EndHour = putDto.EndHour;
                result.EndMinute = putDto.EndMinute;
                result.UpdateTime = DateTime.Now;
                result.EditAdminId = admin.AdminId;
                result.EditAdminName = admin.FullName;
                this.nightFreightConfigurationData.Update(result).GetAwaiter().GetResult();
                string cacheKey = this.redisService.GetKey(key, result.NightFreightConfigurationId);
                this.redisService.DeleteAsync(cacheKey);
                return result.As<NightFreightConfigurationViewDto>();
            }
            else
            {
                //如果是下级代理商，则 代理商夜间运费配置ID 不能为空
                if ((!putDto.AgentNightFreightConfigurationId.HasValue || putDto.AgentNightFreightConfigurationId.Value <= 0)
                        && (!putDto.NightFreightConfigurationId.HasValue || putDto.NightFreightConfigurationId.Value <= 0))
                {
                    throw new ArgumentException("夜间运费配置ID和代理商夜间运费配置ID不能都为空");
                }
                if (putDto.AgentNightFreightConfigurationId.HasValue && putDto.AgentNightFreightConfigurationId.Value > 0)
                {
                    var result = this.agentNightFreightConfigurationData.GetEntity(putDto.AgentNightFreightConfigurationId.Value).Result;
                    if (result == null)
                    {
                        throw new ArgumentException("代理商夜间运费配置信息不存在");
                    }
                    result.OrderExtractProportion = putDto.OrderExtractProportion;
                    result.StartHour = putDto.StartHour;
                    result.StartMinute = putDto.StartMinute;
                    result.EndHour = putDto.EndHour;
                    result.EndMinute = putDto.EndMinute;
                    result.UpdateTime = DateTime.Now;
                    result.EditAdminId = admin.AdminId;
                    result.EditAdminName = admin.FullName;
                    this.agentNightFreightConfigurationData.Update(result).GetAwaiter().GetResult();
                    string cacheKey = this.redisService.GetKey(viewKey, result.AgentNightFreightConfigurationId);
                    this.redisService.DeleteAsync(cacheKey);
                    return result.As<NightFreightConfigurationViewDto>();
                }
                else
                {
                    var agentRecord = this.agentRecordData.GetEntityByCompanyId(admin.CompanyId).Result;
                    if (agentRecord == null)
                    {
                        throw new ArgumentException("您不归属任何代理商，暂无权限修改");
                    }
                    if (putDto.NightFreightConfigurationId.Value <= 0)
                    {
                        throw new ArgumentException("夜间运费配置ID不能为空");
                    }
                    var result = this.agentNightFreightConfigurationData.GetById(agentRecord.AgentRecordId, putDto.NightFreightConfigurationId.Value).Result;
                    if (result == null)
                    {
                        result = this.agentNightFreightConfigurationData.Insert(new AgentNightFreightConfigurationEntity()
                        {
                            AgentRecordId = agentRecord.AgentRecordId,
                            OrderExtractProportion = putDto.OrderExtractProportion,
                            StartHour = putDto.StartHour,
                            StartMinute = putDto.StartMinute,
                            EndHour = putDto.EndHour,
                            EndMinute = putDto.EndMinute,
                            CreateTime = DateTime.Now,
                            CreateAdminId = admin.AdminId,
                            CreateAdminName = admin.FullName,
                            UpdateTime = DateTime.Now,
                            EditAdminId = admin.AdminId,
                            EditAdminName = admin.FullName
                        }).GetAwaiter().GetResult();
                        this.redisService.DeleteAsync(viewKey);
                        return result.As<NightFreightConfigurationViewDto>();
                    }
                    else
                    {
                        result.OrderExtractProportion = putDto.OrderExtractProportion;
                        result.StartHour = putDto.StartHour;
                        result.StartMinute = putDto.StartMinute;
                        result.EndHour = putDto.EndHour;
                        result.EndMinute = putDto.EndMinute;
                        result.UpdateTime = DateTime.Now;
                        result.EditAdminId = admin.AdminId;
                        result.EditAdminName = admin.FullName;
                        this.agentNightFreightConfigurationData.Update(result).GetAwaiter().GetResult();
                        string cacheKey = this.redisService.GetKey(viewKey, result.AgentNightFreightConfigurationId);
                        this.redisService.DeleteAsync(cacheKey);
                        return result.As<NightFreightConfigurationViewDto>();
                    }
                }
            }
        }
    }
}
